﻿
using System.Net;
using DTCash.Logger;
using DTCash.Logger.DTO;
using DTCash.Redis;
using RabbitMQCommon;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using Uranus.Common;
using Uranus.Service.OtherService;
using Uranus.Service.UserService;
using Uranus.WeiStationAPI.Common;
using Uranus.WeiStationAPI.Models;

namespace Uranus.WeiStationAPI.Controllers
{
    [Visit]
    public class BaseController : ApiController
    {
        internal ResultResPonse resultResPonse;
        internal UserInfo UserInfo = new UserInfo();
        internal Uranus.WeiStationAPI.Models.VisitDTO visitDTO;
        internal int TerminalTypeId = 0;//设备id  1	android   2	ios    3	wp8   4	other      
        internal int clientSite = 1;//客户端 1 浏览器 2 微信 3 app
        internal Dictionary<string, object> parmsList;
        internal HttpFileCollectionBase fileCollection;
        internal ControllerDTO CurrentControllerDto;
        private readonly static string[] SSONoCheckAction = new[]
            {"loginout", "wxunbinding", "wxlogin", "wxbinding", "getdisclosuredata"};

        /// <summary>
        /// 获取请求key数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        internal T GetParmsKey<T>(string key)
        {
            if (!string.IsNullOrEmpty(key) && parmsList.ContainsKey(key.ToLower()))
            {
                return (T)Convert.ChangeType(parmsList[key.ToLower()], typeof(T));
            }
            return default(T);
        }

        /// <summary>
        /// 添加注释发送
        /// </summary>
        /// <param name="resultResPonse"></param>
        /// <returns></returns>
        internal ResultResPonse Send(ResultResPonse resultResPonse)
        {
            resultResPonse = Common.ResPonseDataCommon.ResPonseDataHandle(resultResPonse);
            return resultResPonse;
        }

        /// <summary>
        /// api进入时执行
        /// </summary>
        /// <param name="controllerContext"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public override Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
        {
            #region 时间监控开始
            var stopWatch = new System.Diagnostics.Stopwatch();
            stopWatch.Start();
            controllerContext.Request.Properties.Add("__action_duration__", stopWatch);
            #endregion

            resultResPonse = new ResultResPonse() { code = 0 };
            HttpContextBase contextBase = controllerContext.Request.Properties["MS_HttpContext"] as HttpContextBase;
            if (contextBase != null && contextBase.Request.Files != null)
            {
                fileCollection = contextBase.Request.Files;
            }

            //解密请求参数
            this.DecryptParamsList(contextBase);
            //设置控制器特性值
            this.SetControllerDto(controllerContext);
            //设置登录用户的UserInfo
            string uid = (parmsList["u_id"] ?? string.Empty).ToString();
            if (CurrentControllerDto.VisitUserStateEnum != VisitUserStateEnum.NoLogin && uid.Length == 32 || uid.StartsWith("_"))
            {
                this.SetUserInfo(uid);
            }
            //验证请求是否符合action特性设置
            this.ActionAttributeSend(controllerContext);

            #region action属性逻辑验证  未优化过的已注释

            //string action = controllerContext.RouteData.Values["action"].ToString().ToLower();
            //bool isend = false;
            //if (CommonModel.RequestCoerciveEncryption && enEncryption) //检测是否强制加密访问
            //{
            //    if (GetParmsKey<string>("_e") != "1")
            //    {
            //        resultResPonse.code = 17; //非法访问 
            //        //停止执行后续方法 返回指定的值
            //        controllerContext.Request.Properties.Add("RequestEnd_Response",
            //            controllerContext.Request.CreateResponse(HttpStatusCode.OK,
            //                Send(resultResPonse)));
            //        isend = true;
            //    }
            //}
            ////检测是否有参数 _s 此参数作为访问的一个标志 可以作为流程操作记录
            //if (!isend)
            //{
            //    if (!parmsList.ContainsKey("_s"))
            //    {
            //        resultResPonse.code = 15;
            //        controllerContext.Request.Properties.Add("RequestEnd_Response",
            //                                                 controllerContext.Request.CreateResponse(HttpStatusCode.OK,
            //                                                                                          Send(resultResPonse)));
            //        isend = true;
            //    }
            //}
            //if (Validates.GetInt(ConfigCenterWork.GetConfigValueByOperationType(16)) == 0)
            //{
            //    if (!isend && action != "loginout" && action != "wxunbinding" && action != "wxlogin" && action != "wxbinding" && action != "getdisclosuredata")
            //    {
            //        if (UserInfo != null && UserInfo.UserID > 0 && !UserInfo.LoginState)
            //        {
            //            resultResPonse.code = 016; //异常登录 
            //            //停止执行后续方法 返回指定的值
            //            controllerContext.Request.Properties.Add("RequestEnd_Response",
            //                controllerContext.Request.CreateResponse(
            //                    HttpStatusCode.OK, Send(resultResPonse)));
            //            isend = true;
            //        }
            //    }
            //}
            //if (!isend) //检测用户是否登陆
            //{
            //    if ((enlogin && (UserInfo == null || UserInfo.UserID <= 0)))
            //    {

            //        resultResPonse.code = 8; //用户未登陆 
            //        //停止执行后续方法 返回指定的值
            //        controllerContext.Request.Properties.Add("RequestEnd_Response",
            //                                                 controllerContext.Request.CreateResponse(HttpStatusCode.OK,
            //                                                                                          Send(resultResPonse)));
            //        isend = true;
            //    }
            //}
            //if (!isend)
            //{
            //    if (enAuthHuifu)
            //    {
            //        if (UserInfo == null || UserInfo.UserID <= 0)
            //        {
            //            resultResPonse.code = 8; //用户未登陆 
            //            //停止执行后续方法 返回指定的值
            //            controllerContext.Request.Properties.Add("RequestEnd_Response",
            //                controllerContext.Request.CreateResponse(HttpStatusCode.OK, Send(resultResPonse)));
            //            isend = true;
            //        }
            //        else if (string.IsNullOrEmpty(UserInfo.HuiFuCode))
            //        {
            //            resultResPonse.code = 119; //用户未开通汇付 
            //            //停止执行后续方法 返回指定的值
            //            controllerContext.Request.Properties.Add("RequestEnd_Response",
            //                controllerContext.Request.CreateResponse(HttpStatusCode.OK, Send(resultResPonse)));
            //            isend = true;
            //        }
            //    }
            //}

            #endregion

            //添加请求参数 后续会使用
            controllerContext.Request.Properties.Add("Parameter", parmsList);

            #region 初始化参数

            visitDTO = new Uranus.WeiStationAPI.Models.VisitDTO();
            Uranus.Common.VisitCommon visitCommon = new Uranus.Common.VisitCommon();
            visitCommon.SetVisit(HttpContext.Current.Request);
            visitDTO.MajorVersion = visitCommon.MajorVersion;
            visitDTO.BrowserName = visitCommon.BrowserName;
            visitDTO.Browsertype = visitCommon.Browsertype;
            visitDTO.Platform = visitCommon.Platform;
            visitDTO.Url = visitCommon.Url;
            visitDTO.UserAgent = visitCommon.UserAgent;
            visitDTO.UserHostAddress = visitCommon.UserHostAddress;
            visitDTO.UserHostName = visitCommon.UserHostName;
            visitDTO.UrlReferrer = visitCommon.UrlReferrer;
            controllerContext.Request.Properties.Add("VisitDTO", visitDTO);


            if (parmsList.ContainsKey("terminal"))//设备
            {
                if (parmsList["terminal"].ToString() == "android")
                {
                    TerminalTypeId = 1;
                }
                else if (parmsList["terminal"].ToString() == "ios")
                {
                    TerminalTypeId = 2;
                }
            }
            if (parmsList.ContainsKey("_site"))//站点
            {
                switch (parmsList["_site"].ToString())
                {
                    case "1":
                        clientSite = 1; break;
                    case "2":
                        clientSite = 2; break;
                    case "3":
                        clientSite = 3; break;
                }
            }

            #endregion

            return base.ExecuteAsync(controllerContext, cancellationToken);
        }

        #region 获取redis用户缓存
        /// <summary>
        /// 后台保存用户
        /// </summary>
        /// <param name="userInfo"></param>
        /// <param name="key"></param>
        internal void SaveUser(UserInfo userInfo, string key)
        {
            if (userInfo.UserID <= 0) return;
            CacheRedis.AddCache(new TimeSpan(240, 0, 0), CacheItem.InitByIdentity("LoginState", key).Other.other, userInfo);
        }
        /// <summary>
        /// 后台保存用户
        /// </summary>
        /// <param name="userInfo"></param>
        /// <param name="userLoginState"></param>
        internal void SaveUser(UserInfo userInfo, UserLoginState userLoginState)
        {
            if (userInfo.UserID <= 0) return;
            CacheRedis.AddCache(new TimeSpan(240, 0, 0), CacheItem.InitByIdentity(userLoginState.UserID.ToString(), "LoginState", userLoginState.Ext).Other.other, userInfo);
        }
        /// <summary>
        /// 根据标志获取用户id
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        private UserInfo GetUser(string key)
        {
            UserInfo user = CacheRedis.GetCache(CacheItem.InitByIdentity("LoginState", key).Other.other) as UserInfo;
            return user;
        }
        /// <summary>
        /// 根据标志获取用户
        /// </summary>
        /// <param name="userid"></param>
        /// <param name="par"></param>
        /// <returns></returns>
        private UserInfo GetUser(UserLoginState userLoginState)
        {
            UserInfo user = CacheRedis.GetCache(CacheItem.InitByIdentity(userLoginState.UserID.ToString(), "LoginState", userLoginState.Ext).Other.other) as UserInfo;
            return user;
        }
        /// <summary>
        /// 移除登陆用户
        /// </summary>
        /// <param name="userLoginState"></param>
        private void RemoveUser(UserLoginState userLoginState)
        {
            CacheRedis.DelCacheKey(CacheItem.InitByIdentity(userLoginState.UserID.ToString(), "LoginState", userLoginState.Ext).Other.other);
        }
        #endregion

        #region 用户信息处理

        /// <summary>
        /// 获取用户数据
        /// </summary>
        /// <param name="UserID"></param>
        /// <param name="userDto">登录和注册的时候查询出来了所以不用再去查询一次</param>
        /// <returns></returns>
        internal UserInfo GetUserInfoByUserID(int UserID)
        {
            UserInfo user = new UserInfo();
            UserDTO userDto = new UserDTO();
            //获取用户信息
            if (UserID > 0)
            {
                userDto = Uranus.Service.User.GetUser().GetUserByUserID(UserID) ?? new UserDTO();
            }
            //获取用户金额信息
            UserHomePagePriceResponse priceRes = Uranus.Service.User.GetUser().GetUserHomePagePriceResponse(userDto.UserID);
            //获取用户额外收益
            UserGiftCardResponse extraProfit = Uranus.Service.User.GetUser().GetUserGiftCardDTOByParams(
                new UserGiftCardRequest
                {
                    UserID = userDto.UserID,
                    UserGiftCardStatusID = 2
                });
            if (priceRes != null)
            {
                user.UsablePrice = priceRes.UsablePrice;
                user.DQInvestingPrice = priceRes.DQInvestingPrice;
                user.DQPredictEarning = priceRes.DQPredictEarning;
                user.DQAllInvestedPrice = priceRes.DQAllInvestedPrice;
                user.CashFreezePrice = priceRes.CashFreezePrice;
                user.InvestFreezePrice = priceRes.InvestFreezePrice;
                user.DQEarning = priceRes.DQEarning;
                user.InvestCount = priceRes.InvestCount;
                user.CurrentInvestingPrice = priceRes.CurrentInvestingPrice;
                user.CurrentShortProfit = priceRes.CurrentShortProfit;
                user.CurrentYesterdayProfit = priceRes.CurrentYesterdayProfit;
                user.CurrentTotalProfit = priceRes.CurrentTotalProfit;
            }
            if (extraProfit != null && extraProfit.Code == 1)
            {
                user.ExtraProfit = extraProfit.UserGiftCardDtos.Sum(a => a.Price);
            }
            user.BirthDate = userDto.BirthDate;
            user.UserName = userDto.UserName;
            user.Mobile = userDto.Mobile;
            user.MobileAuthStatusID = userDto.MobileAuthStatusID;
            user.CreateTime = userDto.CreateTime;
            user.Email = userDto.Email;
            user.EmailAuthStatusID = userDto.EmailAuthStatusID;
            user.FullName = userDto.FullName;
            user.IDCard = userDto.IDCard;
            user.InvitationCode = userDto.InvitationCode;
            user.InvitationUserID = userDto.InviteUserID;
            user.Sex = userDto.Sex;
            user.UserFromID = userDto.UserFromID;
            user.UserID = userDto.UserID;
            user.IDCardAuthStatusID = userDto.IDCardAuthStatusID;
            user.HuiFuCode = userDto.HuiFuCode;
            user.HuiFuName = userDto.HuiFuName;
            user.HuiFuCreateTime = userDto.HuiFuCreateTime;
            user.LoginState = UserInfo != null && UserInfo.UserID > 0 && UserInfo.LoginState;
            user.UserPhoto = userDto.UserPhoto;
            //获取用户金额信息
            return user;
        }


        internal void UserQuit()
        {
            if (UserInfo.UserID > 0)
            {
                if (parmsList["u_id"].ToString().StartsWith("_"))
                {
                    UserLoginState userLoginState = new UserLoginState(parmsList["u_id"].ToString().Substring(1));
                    RemoveUser(userLoginState);
                }
                else
                {
                    CacheRedis.DelCacheKey(CacheItem.InitByIdentity("LoginState", parmsList["u_id"].ToString()).Other.other);
                }
            }
        }
        #endregion

        #region SourceHandle

        internal void SourceHandle(Uranus.Service.OtherService.SourceOperation sourceOperation, string sourceExtendValue, int sourceExtendNumber, int sourceTypeId)
        {

            if (UserInfo != null)
            {
                if (!string.IsNullOrEmpty(visitDTO.Url) && visitDTO.Url.Length > 200)
                {
                    visitDTO.Url = visitDTO.Url.Substring(0, 200);
                    LogHelper.WriteLogError("记录source超出长度 截取", "", parmsList);
                }
                if (!string.IsNullOrEmpty(visitDTO.UrlReferrer) && visitDTO.UrlReferrer.Length > 200)
                {
                    visitDTO.UrlReferrer = visitDTO.UrlReferrer.Substring(0, 200);
                    LogHelper.WriteLog(LogEnum.Info, "记录source超出长度 截取", visitDTO.UrlReferrer);
                    LogHelper.WriteLogError("记录source超出长度 截取", "", parmsList);
                }
                Dictionary<string, object> dictionary = new Dictionary<string, object>();
                dictionary.Add("cmdid", "addmainsource");
                dictionary.Add("sourceDTO", new Uranus.Service.OtherService.SourceDTO()
                {
                    SourceExtendValue = sourceExtendValue,
                    SourceExtendNumber = sourceExtendNumber,
                    //SourceExtendTypeID = sourceExtendTypeID,
                    SourceOperationID = sourceOperation,
                    SourceSiteID = SourceSite.None,
                    SourceTypeID = sourceTypeId,
                    //Url = visitDTO.Url,
                    //UrlReferrer = visitDTO.UrlReferrer,
                    UserID = UserInfo.UserID,
                    UserIP = visitDTO.UserHostAddress,
                    CreateTime = DateTime.Now,
                    TerminalTypeID = TerminalTypeId == 1 ? TerminalType.Android : TerminalTypeId == 2 ? TerminalType.Ios : TerminalType.None
                });

                RabbitMQConfig rabbitMqConfig = RabbitMQConfigManagement.GetDefaultConfig();
                rabbitMqConfig.queuename = "invoketransfermq";
                rabbitMqConfig.routingKey = "uranusinvoketransfer";
                RabitMQHandler.AddQueue(dictionary, rabbitMqConfig);
            }
        }
        #endregion

        #region action 属性逻辑验证

        /// <summary>
        /// 
        /// </summary>
        /// <param name="controllerContext"></param>
        private void ActionAttributeSend(HttpControllerContext controllerContext)
        {
            string action = controllerContext.RouteData.Values["action"].ToString().ToLower();
            bool isend = false;
            string _e = GetParmsKey<string>("_e");
            string _s = GetParmsKey<string>("_s");
            if (CommonModel.RequestCoerciveEncryption && this.CurrentControllerDto.enEncryption && !_e.Equals("1")) //检测是否强制加密访问
            {
                resultResPonse.code = 17;   //非法访问
            }
            else if (!this.parmsList.ContainsKey("_s"))
            {
                resultResPonse.code = 15;   //请求非法
            }
            else if (this.DetectionUserSSO(action))
            {
                resultResPonse.code = 16; //异常登录 该账户已在其他设备登录
            }
            else if ((this.CurrentControllerDto.VisitUserStateEnum == VisitUserStateEnum.MustLogin || CurrentControllerDto.VisitUserStateEnum == VisitUserStateEnum.ObtainUserInfo) && (UserInfo == null || UserInfo.UserID <= 0))
            {
                resultResPonse.code = 8; //用户未登陆
            }
            else if (this.CurrentControllerDto.enAuthHuifu)
            {
                if (UserInfo == null || UserInfo.UserID <= 0)
                {
                    resultResPonse.code = 8; //用户未登陆
                }
                else if (string.IsNullOrEmpty(UserInfo.HuiFuCode))
                {
                    resultResPonse.code = 119; //用户未开通汇付 
                }
            }
            if (resultResPonse.code != 0)
            {
                controllerContext.Request.Properties.Add("RequestEnd_Response",
                    controllerContext.Request.CreateResponse(HttpStatusCode.OK,
                        Send(resultResPonse)));
            }
        }

        /// <summary>
        /// 设置当前控制器DTO  用于读取action特性
        /// </summary>
        /// <param name="controllerContext"></param>
        private void SetControllerDto(HttpControllerContext controllerContext)
        {
            this.CurrentControllerDto = ControllerProperty.GetCurrentControllerDto(
                                            controllerContext.Controller.ToString().ToLower(),
                                            controllerContext.RouteData.Values["action"].ToString().ToLower()) ??
                                        new ControllerDTO()
                                        {
                                            VisitUserStateEnum = VisitUserStateEnum.NoLogin, //是否启用用户登陆强制验证
                                            enEncryption = true, //是否加密
                                            enAuthHuifu = false, //认证汇付编号
                                        };
        }

        /// <summary>
        /// 解密参数
        /// </summary>
        private void DecryptParamsList(HttpContextBase contextBase)
        {
            if (contextBase == null)
            {
                throw new ArgumentNullException(nameof(contextBase), "decrypt params contextBase is null ");
            }
            this.parmsList = CodeCommon.ConvertParams(contextBase.Request);
            if (GetParmsKey<string>("_e") == "1")//验证是否需要解密
            {
                string _d = GetParmsKey<string>("_d");
                if (!string.IsNullOrEmpty(_d))
                {
                    try
                    {
                        Dictionary<string, object> dictionary =
                            Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>>(
                                Common.RequestDecrypt.Decrypt(_d));
                        if (dictionary != null)
                        {
                            foreach (KeyValuePair<string, object> keyValuePair in dictionary)
                            {
                                parmsList.Add(keyValuePair.Key, keyValuePair.Value);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        LogHelper.WriteLogError("解密请求出现异常", ex.Message, parmsList, true);
                    }
                }
            }
        }

        /// <summary>
        /// 设置用户详情信息
        /// </summary>
        private void SetUserInfo(string uid)
        {
            if (string.IsNullOrEmpty(uid))
            {
                throw new ArgumentNullException(nameof(uid), "uid is null or empty");
            }
            UserLoginState userLoginState = null;
            //新用户登陆方式获取 通过_ + DES加密的串
            if (uid.StartsWith("_"))
            {
                userLoginState = new UserLoginState(uid.Substring(1));
                UserInfo = GetUser(userLoginState) ?? new UserInfo();
            }
            else
            {
                UserInfo = GetUser(uid) ?? new UserInfo();
            }
            parmsList.Add("UserID", UserInfo.UserID);

            if (UserInfo.UserID != 0 && CurrentControllerDto.VisitUserStateEnum == VisitUserStateEnum.ObtainUserInfo)
            {
                UserInfo = GetUserInfoByUserID(UserInfo.UserID);  //获取用户信息 
                try
                {
                    if (userLoginState != null)
                    {
                        SaveUser(UserInfo, userLoginState);
                    }
                    else
                    {
                        SaveUser(UserInfo, uid);
                    }
                }
                catch (Exception exception)
                {
                    LogHelper.WriteLogError("base保存userinfo出现异常", exception.Message, parmsList);
                }
            }
        }

        /// <summary>
        /// 检测用户单点登录
        /// </summary>
        /// <returns></returns>
        public bool DetectionUserSSO(string action)
        {
            object configValue = ConfigCenterWork.GetConfigValueByOperationType(16) ?? 0;
            return configValue.ToString().Equals("0") &&
                   !SSONoCheckAction.Contains(action) &&
                   UserInfo != null && UserInfo.UserID > 0 && !UserInfo.LoginState;
        }

        #endregion
    }
}
